﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Picdownload
{
    public class ParseResource
    {
        public string parentUrl;
        public List<string> patterns = new List<string>();

        // 获得html中的 
        //private void getA()
        //{
        //    char[] buffer = new char[1024];
        //    int state = 0;
        //    String a = "";
        //    while (!sr.EndOfStream)
        //    {
        //        int n = sr.Read(buffer, 0, buffer.Length);
        //        for (int i = 0; i < n; i++)
        //        {
        //            switch (state)
        //            {
        //                case 0: // 状态0 
        //                    if (buffer[i] == '<') // 读入的是'<' 
        //                    {
        //                        a += buffer[i];
        //                        state = 1; // 切换到状态1 
        //                    }
        //                    break;
        //                case 1: // 状态1 
        //                    if (buffer[i] == 'a' || buffer[i] == 'A') // 读入是'a'或'A' 
        //                    {
        //                        a += buffer[i];
        //                        state = 2; // 切换到状态2 
        //                    }
        //                    else
        //                    {
        //                        a = "";
        //                        state = 0; // 切换到状态0 
        //                    }
        //                    break;
        //                case 2: // 状态2 
        //                    if (buffer[i] == ' ' || buffer[i] == '\t') // 读入的是空格或'/t' 
        //                    {
        //                        a += buffer[i];
        //                        state = 3;
        //                    }
        //                    else
        //                    {
        //                        a = "";
        //                        state = 0; // 切换到状态0 
        //                    }
        //                    break;
        //                case 3: // 状态3 
        //                    if (buffer[i] == '>') // 读入的是'>'，已经成功获得一个 
        //                    {
        //                        a += buffer[i];
        //                        try
        //                        {
        //                            string url = getUrl(getHref(a)); // 获得中的href属性的值 
        //                            if (url != null)
        //                            {
        //                                if (findUrl != null)
        //                                    findUrl(url); // 引发发现url的事件 
        //                            }
        //                        }
        //                        catch (Exception e)
        //                        {
        //                        }
        //                        state = 0; // 在获得一个后，重新切换到状态0 
        //                    }
        //                    else
        //                        a += buffer[i];
        //                    break;
        //            }
        //        }
        //    }
        //}


        // 从中获得Href 
        public List<string> getHref(string a)
        {
            try
            {
                List<string> lstReturn = new List<string>();
                string p = @"href/s*=/s*('[^']*'|""[^""]*""|/S+/s+)"; // 获得Href的正则表达式 
                MatchCollection matches = Regex.Matches(a, p,
                RegexOptions.IgnoreCase |
                RegexOptions.ExplicitCapture);
                foreach (Match nextMatch in matches)
                {
                    lstReturn.Add(getUrl(nextMatch.Value)); // 返回href 
                }
                return lstReturn;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        // 从href中提取url 
        public String getUrl(string href)
        {
            try
            {
                if (href == null) return href;
                int n = href.IndexOf('='); // 查找'='位置 
                String s = href.Substring(n + 1);
                int begin = 0, end = 0;
                string sign = "";
                if (s.Contains("\"")) // 第一种情况 
                    sign = "\"";
                else if (s.Contains("'")) // 第二种情况 
                    sign = "'";
                else // 第三种情况 
                    return getFullUrl(s.Trim());
                begin = s.IndexOf(sign);
                end = s.LastIndexOf(sign);
                return getFullUrl(s.Substring(begin + 1, end - begin - 1).Trim());
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        // 将相对路径变为绝对路径 
        private String getFullUrl(string url)
        {
            try
            {
                if (url == null) return url;
                if (processPattern(url)) return null; // 过滤不想下载的url 
                // 如果url前有http://或https://，为绝对路径，按原样返回 
                if (url.ToLower().StartsWith("http://") || url.ToLower().StartsWith("https://"))
                    return url;
                Uri parentUri = new Uri(parentUrl);
                string port = "";
                if (!parentUri.IsDefaultPort)
                    port = ":" + parentUri.Port.ToString();
                if (url.StartsWith("/")) // url以"/"开头，直接放在host后面 
                    return parentUri.Scheme + "://" + parentUri.Host + port + url;
                else // url不以"/"开头，放在url的路径后面 
                {
                    string s = "";
                    s = parentUri.LocalPath.Substring(0, parentUri.LocalPath.LastIndexOf("/"));
                    return parentUri.Scheme + "://" + parentUri.Host + port + s + "/" + url;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        // 如果返回true，表示url符合pattern，否则，不符合模式
        private bool processPattern(string url)
        {
            foreach (string p in patterns)
            {

                if (Regex.IsMatch(url, p, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture)
                && !p.Equals(""))
                    return true;
            }
            return false;
        }
    }
}